#ifndef SHOW_H
#define SHOW_H

#include <QWidget>
#include <QKeyEvent>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QPainter>
#include <QPen>
#include <QImage>
#include <QDebug>
#include <QTimer>
#include <QPoint>

#include <vector>
#include <iostream>
#include "show3d.h"


using namespace std;


typedef struct{
    QPoint p1,p2;
    int c1,c2;
}Line;

namespace Ui {
class Show;
}


class Show : public QWidget
{
    Q_OBJECT

public:
    explicit Show(QWidget *parent = 0);
    ~Show();

    show3d show2;

    void keyPressEvent(QKeyEvent *ev);
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *event);

    void init(char imageName[]);

    void setColor1(int c){
        color1=c;
        if(color1>255)
            color1=255;
        else if(color1<1)
            color1=1;
    }

    void setColor2(int c){
        color2=c;
        if(color2>255)
            color2=255;
        else if(color2<1)
            color2=1;
    }

    void clear_newdata()
    {
        for(int i=0;i<w;i++)
            memset(newdata[i],0,h*sizeof(int));
    }

    void back_toLast()
    {
        for(int i=0;i<w;i++)
        {
            for(int j=0;j<h;j++)
            {
                if(newdata[i][j]==step_num)
                {
                    data[i][j]=0;
                    newdata[i][j]=0;
                }
            }
        }
        if(step_num!=0)
            step_num--;
    }

    void drawline_indata(int sx, int sy, int ex, int ey, int c1, int c2) // draw a line
    {
        double l=sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy));
        double c_step=1.0*(c2-c1)/l;
        double x_step=(ex-sx)/l;
        double y_step=(ey-sy)/l;

        for(int i=0;i<=(int)l;i++)
        {
            if(data[(int)(sx+x_step*i)][(int)(sy+y_step*i)]==0)
                newdata[(int)(sx+x_step*i)][(int)(sy+y_step*i)]=step_num;
            data[(int)(sx+x_step*i)][(int)(sy+y_step*i)]=(int)(c1+c_step*i);
        }
    }


    void drawline_indata(int x, int y, int h, int c1, int c2)   //draw a hori line y->y+h
    {
//        clear_newdata();
        double step=1.0*(c2-c1)/h;
        for(int i=0;i<=h;i++)
        {
            if(data[x][y+i]==0)
                newdata[x][y+i]=step_num;
            data[x][y+i]=(int)(c1+step*i);
        }
    }

    void drawRect_indata(int sx, int sy, int ex, int ey)    //draw rect in x->0
    {
        double l=sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy));
        double x_step=(ex-sx)/l;
        double y_step=(ey-sy)/l;

        for(int n=0;n<=l;n++)
        {
            int y=sy+y_step*n;
            int x=sx+x_step*n;
            for(int i=x-1;i>=0;i--)
            {
                if(data[i][y]!=0)
                {
                    drawline_indata1(i,y,(x-i),data[i][y],data[x][y]);
                    break;
                }
            }
        }
    }

    void drawRect_indata_r(int sx, int sy, int ex, int ey)    //draw rect in x->W
    {
        double l=sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy));
        double x_step=(ex-sx)/l;
        double y_step=(ey-sy)/l;

        for(int n=0;n<=l;n++)
        {
            int y=sy+y_step*n;
            int x=sx+x_step*n;
            for(int i=x+1;i<w;i++)
            {
                if(data[i][y]!=0)
                {
                    drawline_indata1(x,y,(i-x),data[x][y],data[i][y]);
                    break;
                }
            }
        }

    }

    void drawRect_indata_h(int sx, int sy, int ex, int ey)    //draw rect in y->0
    {
        double l=sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy));
        double x_step=(ex-sx)/l;
        double y_step=(ey-sy)/l;

        for(int n=0;n<=l;n++)
        {
            int y=sy+y_step*n;
            int x=sx+x_step*n;
            for(int j=y-1;j>=0;j--)
            {
                if(data[x][j]!=0)
                {
                    drawline_indata(x,j,x,y,data[x][j],data[x][y]);
                    break;
                }
            }
        }

    }

    void drawRect_indata_h1(int sx, int sy, int ex, int ey)    //draw rect in y->0
    {
        double l=sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy));
        double x_step=(ex-sx)/l;
        double y_step=(ey-sy)/l;

        for(int n=0;n<=l;n++)
        {
            int y=sy+y_step*n;
            int x=sx+x_step*n;
            for(int j=y+1;j<h;j++)
            {
                if(data[x][j]!=0)
                {
                    drawline_indata(x,j,x,y,data[x][j],data[x][y]);
                    break;
                }
            }
        }

    }

    void drawline_indata1(int x, int y, int w, int c1, int c2) //draw vertical line, w
    {
        double step=1.0*(c2-c1)/w;
        for(int i=1;i<=w;i++)
        {
            if(data[x+i][y]==0)
                newdata[x+i][y]=step_num;
            data[x+i][y]=(int)(c1+step*i);
        }
    }

    void drawRect_indata(int x, int y, int h)//draw rect in x->0
    {
        for(int j=0;j<=h;j++)
        {
            for(int i=x-1;i>=0;i--)
            {
                if(data[i][y+j]!=0)
                {
                    drawline_indata1(i,y+j,(x-i),data[i][y+j],data[x][y+j]);
                    break;
                }
            }
        }

    }

    void savedata(char filename[])
    {
        QImage img(w,h, QImage::Format_RGB32);
        for(int i=0;i<w;i++)
        {
            for(int j=0;j<h;j++)
            {
                img.setPixelColor(i,j,QColor(data[i][j],data[i][j],data[i][j]));
            }
        }
        img.save(filename);

        FILE *p;
        if(strcmp(filename,"data.png")==0)
            p=fopen("data.step","w");
        else
            p=fopen("temp.step","w");

        fprintf(p,"%d\n",step_num);
        for(int i=0;i<w;i++)
        {
            for(int j=0;j<h;j++)
            {
                fprintf(p,"%d\n",newdata[i][j]);
            }
        }
        fclose(p);
    }

    void reloadData(char filename[])
    {
        QImage img(filename);
        if(img.width()!=w||img.height()!=h)
            return ;
        for(int i=0;i<w;i++)
        {
            for(int j=0;j<h;j++)
            {
                data[i][j]=qRed(img.pixel(i,j));
            }
        }
        drawPlace=lines.size();

        FILE *p;
        if(strcmp(filename,"data.png")==0)
            p=fopen("data.step","r");
        else
            p=fopen("temp.step","r");

        if(p==NULL)
            return ;

        fscanf(p,"%d",&step_num);
        for(int i=0;i<w;i++)
        {
            for(int j=0;j<h;j++)
            {
                fscanf(p,"%d",&newdata[i][j]);
            }
        }
        fclose(p);

        this->update();
    }

    void setDrawLineMode(bool mode)
    {
        single_mode=mode;
    }

    QImage back;

    int color1;
    int color2;

    unsigned char **data;
    unsigned int **newdata;
    unsigned int step_num;
    int drawPlace;
    int lastPlace;

    int w,h;

    QPoint points[2];

    vector<Line> lines;

    int lmx,lmy;
    int rmx,rmy;

    bool single_mode;
    bool mode;

    void setMode(bool b)
    {
        mode=b;
    }

private:
    Ui::Show *ui;
    double rate;
    int startx,starty;
};

#endif // SHOW_H
